package java_thinking.unit_21._21_4;

import net.jcip.annotations.ThreadSafe;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * @Desc:   4-16 通过组合实现线程安全的-若没有则添加 功能
 *              1.与Collections.synchronizedList和其他容器封装器一样，ImprovedList假设把
 *              某个链表对象传给构造函数以后，客户代码不会再直接使用这个对象，而只能通过
 *              ImprovedList来访问它。
 *
 *              2.ImprovedList 通过自身的内置锁增加了一层额外的加锁，它并不关心底层的list
 *              是否是线程安全的，即使List不是线程安全的，或者修改了它的加锁实现，
 *              ImprovedList 也会提供一致的加锁机制来实现线程安全性，事实上，这里是使用了
 *              java监视器模式来封装现有的 List，并且只要在类中拥有指向底层 List 的唯一
 *              外部引用，就能保证线程安全性
 * @author: cww
 * @DateTime: 2019-06-03 22:37
 */
@ThreadSafe
public class ImprovedList<T> implements List<T> {
    private final List<T> list;

    public ImprovedList(List<T> list) {
        this.list = list;
    }

    /**
     *
     * @param x
     * @return
     */
    public synchronized boolean putIfAbsent(T x) {
        boolean absent = list.contains(x);
        if (!absent) {
            list.add(x);
        }
        return !absent;
    }
    // Plain vanilla delegation for List methods.
    // Mutative methods must be synchronized to ensure atomicity of putIfAbsent.

    @Override
    public int size() {
        return list.size();
    }
    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }
    @Override
    public boolean contains(Object o) {
        return list.contains(o);
    }
    @Override
    public Iterator<T> iterator() {
        return list.iterator();
    }
    @Override
    public Object[] toArray() {
        return list.toArray();
    }
    @Override
    public <T> T[] toArray(T[] a) {
        return list.toArray(a);
    }
    @Override
    public synchronized boolean add(T e) {
        return list.add(e);
    }
    @Override
    public synchronized boolean remove(Object o) {
        return list.remove(o);
    }
    @Override
    public boolean containsAll(Collection<?> c) {
        return list.containsAll(c);
    }
    @Override
    public synchronized boolean addAll(Collection<? extends T> c) {
        return list.addAll(c);
    }
    @Override
    public synchronized boolean addAll(int index, Collection<? extends T> c) {
        return list.addAll(index, c);
    }
    @Override
    public synchronized boolean removeAll(Collection<?> c) {
        return list.removeAll(c);
    }
    @Override
    public synchronized boolean retainAll(Collection<?> c) {
        return list.retainAll(c);
    }
    @Override
    public boolean equals(Object o) {
        return list.equals(o);
    }
    @Override
    public int hashCode() {
        return list.hashCode();
    }
    @Override
    public T get(int index) {
        return list.get(index);
    }
    @Override
    public T set(int index, T element) {
        return list.set(index, element);
    }
    @Override
    public void add(int index, T element) {
        list.add(index, element);
    }
    @Override
    public T remove(int index) {
        return list.remove(index);
    }
    @Override
    public int indexOf(Object o) {
        return list.indexOf(o);
    }
    @Override
    public int lastIndexOf(Object o) {
        return list.lastIndexOf(o);
    }
    @Override
    public ListIterator<T> listIterator() {
        return list.listIterator();
    }
    @Override
    public ListIterator<T> listIterator(int index) {
        return list.listIterator(index);
    }
    @Override
    public List<T> subList(int fromIndex, int toIndex) {
        return list.subList(fromIndex, toIndex);
    }
    @Override
    public synchronized void clear() { list.clear(); }
}
